﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Diagnostics;

namespace Performance_Test
{
    
    public partial class Performance_Test : Form
    {
        string InputData = String.Empty, data_label_1, data_label_2, data_label_3, data_label_4;
        System.IO.Ports.SerialPort ComPort = new System.IO.Ports.SerialPort();
      
        Stopwatch stopWatch = new Stopwatch();
        TimeSpan st;
        long scaning_time;
        int Expected_Reading_Rate, MiExpected_Reading_Rate;
        string Ex_Reading_Rate, Perform_type, ReceivedData;
        float Motion, Distance;
        int label_num, GoodCount = 0, IncorrectCount = 0, MissRead = 0;
        List<string> expected_data = new List<string>();
        Boolean m_stop = false, flag_form2= true;
        


        public Performance_Test()
        {
            InitializeComponent();
                             
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
            //Init default for all textbox of Motion tolerance tab and combobox of form 1
            cmbSymbology.Text = cmbSymbology.Items[0].ToString();
            cmbResolution.Text = cmbResolution.Items[0].ToString();
            cmbMotion.Text = cmbMotion.Items[10].ToString();
            cmbNumLabel.Text = cmbNumLabel.Items[0].ToString();
            
           // ComPort = new SerialPort("COM55", 115200, Parity.None, 8, StopBits.One);
          //  ComPort.Close();
            GetComPort();//init com port 
            cmbBaud.Text = cmbBaud.Items[5].ToString();
            cmbData.Text = cmbData.Items[3].ToString();
            cmbParity.Text = cmbParity.Items[2].ToString();
            cmbStop.Text = cmbStop.Items[0].ToString();
            Motion = Convert.ToSingle(cmbMotion.Text);
            label_num = Convert.ToInt32(cmbNumLabel.Text);
            Distance = 3 / label_num;
            Perform_type = tabPerformType.SelectedTab.Text.Trim();
            //format string for Expected Reading rate
            Ex_Reading_Rate = txtReadingRate.Text.Trim();
            int len = Ex_Reading_Rate.Length;
            Ex_Reading_Rate = Ex_Reading_Rate.Substring(1, len - 1 - 1);
            Expected_Reading_Rate = Convert.ToInt32(Ex_Reading_Rate);
            txtReadingRate.BackColor = Color.FromKnownColor(KnownColor.Control);
            txtReadingRate.ForeColor = Color.Red;
            txtReadingRate.ReadOnly = true;

            //Init default for all textbox of Missread tab and combobox of form 1
            cmbMiSymbo.Text = cmbSymbology.Items[0].ToString();
            cmbMiResolution.Text = cmbResolution.Items[0].ToString();
            cmbMiMotion.Text = cmbMotion.Items[10].ToString();
            cmbMiNumLabels.Text = cmbNumLabel.Items[0].ToString();
            //format string for Expected Reading rate
            Ex_Reading_Rate = txtMiReadingRate.Text.Trim();
            len = Ex_Reading_Rate.Length;
            Ex_Reading_Rate = Ex_Reading_Rate.Substring(1, len - 1 - 1);
            MiExpected_Reading_Rate = Convert.ToInt32(Ex_Reading_Rate);
            txtMiReadingRate.BackColor = Color.FromKnownColor(KnownColor.Control);
            txtMiReadingRate.ForeColor = Color.Red;
            txtMiReadingRate.ReadOnly = true;

           
        }


        //Get Com Port of PC
        private void GetComPort()
        {
            string[] ArrayComPortsNames = null;
            int index = -1;
            string ComPortName = null;
            ArrayComPortsNames = System.IO.Ports.SerialPort.GetPortNames();
            do
            {
                index += 1;
                cmbPort.Items.Add(ArrayComPortsNames[index]);
            }

            while (!((ArrayComPortsNames[index] == ComPortName)
                          || (index == ArrayComPortsNames.GetUpperBound(0))));
            Array.Sort(ArrayComPortsNames);

            //want to get first out
            if (index == ArrayComPortsNames.GetUpperBound(0))
            {
                ComPortName = ArrayComPortsNames[0];
            }
            cmbPort.Text = ArrayComPortsNames[0];
        }

        //Receive Data from COM of PC
        private void ReceivedData_1()
        {

            if (ComPort.IsOpen)
            {
                ComPort.DiscardInBuffer();//delete all data in device's received buffer
                ComPort.DiscardOutBuffer();// delete all data in transmit buffer
                ComPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(port_DataReceived_1);
            }


        }

        
        private void btnClearText_Click(object sender, EventArgs e)
        {
            txtReceivedData.Text = "";
            stopWatch.Stop();
            stopWatch.Reset();
            lblScanningTime.Text = "";
            InputData = "";
            scaning_time = 0;
            lblSumLabels.Text = "";
            GoodCount = 0;
            IncorrectCount = 0;
            lblGoodRead.Text = "";
            lblIncorrect.Text = "";
            lblMissRead.Text = "";
            lblReadingRate.Text = "";
            lblMiSumLabels.Text = "";
            lblMiGoodRead.Text = "";
            lblMiIncorrect.Text = "";
            lblMiNoRead.Text = "";
            lblMiReadingRate.Text = "";
            DE_Count = 0;
            MissRead = 0;


        }

        private void btnWriteLog_Click(object sender, EventArgs e)
        {
            string _perform_type, _symbol, _resolution, _distance, _motion, _pitch, _skew, _scanning_time, _reading_rate, _label_num, _filename, _good_read, _incorrect_read, _no_read, _sum_label;
            string _path = Path.GetDirectoryName(Application.ExecutablePath);
            _perform_type = tabPerformType.SelectedTab.Text.Trim();
            switch (_perform_type)
            {
                case "Motion Tolerance":

                    _symbol = cmbSymbology.Text.Trim();
                    _resolution = cmbResolution.Text.Trim();
                    _distance = txtDistance.Text.Trim();
                    _motion = cmbMotion.Text.Trim();
                    _pitch = lblPitch.Text.Trim();
                    _skew = lblSkew.Text.Trim();
                    _scanning_time = scaning_time.ToString();
                    _reading_rate = lblReadingRate.Text.Trim();
                    _label_num = cmbNumLabel.Text.Trim();
                    _good_read = lblGoodRead.Text.Trim();
                    _incorrect_read = lblIncorrect.Text.Trim();
                    _no_read = lblMissRead.Text.Trim();
                    _sum_label = lblSumLabels.Text.Trim();

                    _filename = Execuse.CreateFileName_Motion(_perform_type, _symbol, _resolution, _motion);
                    Execuse.LogFile(_filename, _perform_type, _symbol, _resolution
                        , _distance, _motion, _label_num, _pitch, _skew, _scanning_time, _good_read
                        , _incorrect_read, _no_read, _sum_label, _reading_rate, Expected_Reading_Rate);
                    Test_Label.Text = _filename;
                    break;
                case "Depth Of Field":
                    //       _filename = Execuse.CreateFileName_DOF(_perform_type, _symbol, _resolution, _distance);
                    break;
                case "Pitch":
                    //       _filename = Execuse.CreateFileName_Pitch(_perform_type, _symbol, _resolution, _pitch);
                    break;
                case "Skew":
                    //       _filename = Execuse.CreateFileName_Skew(_perform_type, _symbol, _resolution, _skew);
                    break;
                case "Sweep Mode":
                    //       _filename = Execuse.CreateFileName_SweepMode(_perform_type, _symbol, _resolution, _distance, _motion);
                    break;
                case "Line Efficiency":
                    //       _filename = Execuse.CreateFileName_LineEfficiency(_perform_type, _symbol, _resolution, _distance);
                    break;
                case "Presentation Mode":
                    //     _filename = Execuse.CreateFileName_Presentation(_perform_type, _symbol, _resolution, _motion);
                    break;
                case "Missread":
                    _perform_type = tabPerformType.SelectedTab.Text.Trim();
                    _symbol = cmbMiSymbo.Text.Trim();
                    _resolution = cmbMiResolution.Text.Trim();
                    _distance = txtMiDistance.Text.Trim();
                    _motion = cmbMiSymbo.Text.Trim();
                    _pitch = lblPitch.Text.Trim();
                    _skew = lblSkew.Text.Trim();
                    _scanning_time = scaning_time.ToString();
                    _reading_rate = lblMiReadingRate.Text.Trim();
                    _label_num = cmbMiNumLabels.Text.Trim();
                    _good_read = lblMiGoodRead.Text.Trim();
                    _incorrect_read = lblMiIncorrect.Text.Trim();
                    _no_read = lblMiNoRead.Text.Trim();
                    _sum_label = lblMiSumLabels.Text.Trim();
                    _filename = Execuse.CreateFileName_Missread(_perform_type, _symbol, _resolution, _distance);
                    Execuse.LogFile(_filename, _perform_type, _symbol, _resolution
                         , _distance, _motion, _label_num, _pitch, _skew, _scanning_time, _good_read
                         , _incorrect_read, _no_read, _sum_label, _reading_rate, Expected_Reading_Rate);

                    Test_Label.Text = _filename;
                    break;

            }


        }


        //Open com port
        public void OpenComPort()
        {
            if (!(ComPort.IsOpen))
            {
                try
                {
                    GC.SuppressFinalize(ComPort); 
                    ComPort.Open(); 
                    GC.SuppressFinalize(ComPort.BaseStream);
                    ComPort.DtrEnable = true;                   

                }
                catch (Exception ex)
                {
                    MessageBox.Show("This COM port isn't existing");
                }
                grpTerminal.Text = "Terminal" + "_" + ComPort.PortName + "_Baud: " + ComPort.BaudRate;
            }
            else
            {
                CloseComPort();
            }

        }
        public void CloseComPort()
        {

            try
            {
                GC.ReRegisterForFinalize(ComPort.BaseStream);
                ComPort.Close();
                GC.ReRegisterForFinalize(ComPort);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Can't close COM Port. Because the device is changed to other interface");
            }
            grpTerminal.Text = "Terminal";

        }


        //Received Data
        private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
        {

            int len;
            string last_char;

            tabPerformType.Invoke(new EventHandler(delegate
            {

                Perform_type = tabPerformType.SelectedTab.Text.Trim();

            }));
            
            switch (Perform_type)
            {
                
                case "Motion Tolerance":
                    System.Threading.Thread.Sleep(50);
                    InputData = ComPort.ReadExisting();
                    if (!InputData.Equals(string.Empty))
                    {
                        stopWatch.Start();
                    scaning_time = stopWatch.ElapsedMilliseconds;
                    st = stopWatch.Elapsed;
                    string timestamp = DateTime.Now.ToString("yy:MM:dd:HH:mm:ss:ff");
                    InputData = "[" + timestamp + "]" + InputData;
                    len = InputData.Length;
                    last_char = InputData.Substring(len - 1, 1);
                    txtReceivedData.Invoke(new EventHandler(delegate
                        {

                            txtReceivedData.Text += InputData;
                            if (last_char == "\r")
                            {
                                Execuse.TextReceivedData = txtReceivedData.Text;
                            }
                        }));
                        scanning_display_motion_tolerance();
                    }
                    
                    
                    break;
                case "Missread":

                    System.Threading.Thread.Sleep(50);
                    InputData += ComPort.ReadExisting();
                    if (!InputData.Equals(string.Empty))
                    {
                        stopWatch.Start();

                    
                    scaning_time = stopWatch.ElapsedMilliseconds;
                    st = stopWatch.Elapsed;
                    
                    len = InputData.Length;
                    if (len != 0)
                    {
                        last_char = InputData.Substring(len - 1, 1);

                        txtReceivedData.Invoke(new EventHandler(delegate
                        {
                            if (DE_Count == 0)
                            {
                                txtReceivedData.Text += InputData;
                            }
                            else
                            {
                                txtReceivedData.Text += InputData;
                            }
                            if (last_char == "\r")
                            {
                                Execuse.TextReceivedData = txtReceivedData.Text;
                                MissRead += Execuse.MissRead(DE_Count);
                                DE_Count = 0;
                            }
                        }));
                    }
                    scanning_display_missread();
                    }
                    InputData = "";

                    break;

            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {

            Perform_type = tabPerformType.SelectedTab.Text.Trim();
            flag_form2 = false;
            
            if (!ComPort.IsOpen)
            {

                ComPort.PortName = Convert.ToString(cmbPort.Text);
                ComPort.BaudRate = Convert.ToInt32(cmbBaud.Text);
                ComPort.DataBits = Convert.ToInt16(cmbData.Text);
                ComPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmbStop.Text);
                ComPort.Parity = (Parity)Enum.Parse(typeof(Parity), cmbParity.Text);
                OpenComPort();
            }
            else
            {
                CloseComPort();
            }
            flag_form2 = true;

            switch (Perform_type)
            {
                case "Motion Tolerance":
                   
                    break;
                case "Missread":

                    break;

            }
            if (flag_form2)
            {

                ReceivedData_1();
            }
            


        }

        private void configurationDataToolStripMenuItem_Click(object sender, EventArgs e)
        {

            flag_form2 = false;
            this.Visible = false;

            //Start Form2 but as a dialog 
            //i.e. this thread will be blocked til Form2 instance closed
            (new Form2(ComPort)).ShowDialog();

            //Reshow this form
            this.Visible = true;
            flag_form2 = true;

        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // This event handler is where the actual work is done. 
            // This method runs on the background thread. 

            do
            {

                if (backgroundWorker1.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    // Perform a time consuming operation and report progress.
                    Execuse.Enable_Disable(ComPort);
                }
            } while (m_stop);


        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // This method runs on the main thread.

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // This event handler is called when the background thread finishes. 
            // This method runs on the main thread. 

            if (e.Error != null)
                MessageBox.Show("Error: " + e.Error.Message);

        }


        private void StartThread()
        {
            // Start the asynchronous operation.
            if (backgroundWorker1.IsBusy != true)
            {
                // Start the asynchronous operation.
                backgroundWorker1.RunWorkerAsync();
            }
            else
            {
                MessageBox.Show("backgroundWorker is busying. Needed to be closed backgroundWorker before start it");
            }

        }
        public string MyTxtReceivedData
        {

            get
            {

                txtReceivedData.Invoke(new EventHandler(delegate
              {

                  ReceivedData = txtReceivedData.Text;

              }));
                return ReceivedData;
            }

            set
            {
                txtReceivedData.Invoke(new EventHandler(delegate
                {

                    txtReceivedData.Text = value;

                }));

            }
        }

        private void Performance_Test_FormClosed(object sender, FormClosedEventArgs e)
        {
            
        }

        private void checkDoubleReadTimeoutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //check double read time out
            int _sndr = Execuse.GetDoubleReadTimeOut(ComPort);
            int _time_label = Execuse.TimePassLabels(Motion, label_num);
            //if double read time out greater than the moving time between labels
            if (_sndr > _time_label)
            {
                Execuse.SetDoubleReadTimeout(ComPort, _time_label);

            }
        }
        private void tabPerformType_SelectedIndexChanged(object sender, EventArgs e)
        {
             if(tabPerformType.SelectedTab==tabMisread)
             {
                 tabPerformType.SelectedTab = tabMotionTolerance;
                 //tabPerformType.SelectTab = tabMisread;

             }
             
         }

        
    }
}
